#include <stdio.h>

char Base64_Int(char tem)//字符转Base64编码
{
    if(tem >= 'A'&&tem <= 'Z')
    return tem - 'A';
    else if(tem >= 'a'&&tem <= 'z')
    return tem + 26 - 'a';
    else if(tem >= '0'&&tem <= '9')
    return tem + 52 - '0';
    else if(tem == '+')
    return 62;
    else if(tem == '/')
    return 63;
}

char Base64_Char(int tem)//Base64编码转字符
{
    if(tem >= 0&&tem <= 25)
    return tem + 'A';
    else if(tem >= 26&&tem <= 51)
    return tem + 'a' - 26;
    else if(tem >= 52&&tem <= 61)
    return tem + '0' - 52;
    else if(tem == 62)
    return '+';
    else if(tem == 63)
    return '/';
}

void Into_Char(char* dest, int* src, int flag)//将二进制数转换为char类型//flag==1转换为Base64，flag==0转换为ascll
{
    int tem = 0;
    int n = 1;
    int num = 0;
    if(flag)
    num = 5;
    else
    num = 7;
    for(int i = num; i >= 0; i--)
    {
        tem += *(src + i) * n;
        n *= 2;
    }
    if(flag)
    *dest = Base64_Char(tem);
    else
    *dest = tem;
}

void Into_Binary(int* dest, char src, int flag)//将src转换为二进制存到dest中//flag==1将Base64编码转换为二进制，flag==0将ascll转换为二进制
{
    int n = 2;
    int num = 0;
    if(flag)
    {
        num = 5;
        src = Base64_Int(src);
    }
    else
    {
        num = 7;
    }
    for(int i = num; i >= 0; i--)
    {
        *(dest + i) = src % n;
        src /= 2;
    }
}

void Into_Base64(const char dest[], const char src[])//加密函数//目标文件，源文件
{
    FILE* srcx = fopen(src, "r");
    if(srcx == NULL)
    {
        perror("source:");
        return;
    }
    FILE* destx = fopen(dest, "w");
    if(destx == NULL)
    {
        perror("destination:");
        return;
    }
    int flag = 1;
    while(flag)
    {
        char secret[5] = {0};//存储加密后数据
        int binary[25] = {0};//6和8的最小公倍数为24
        char ch = 0;
        for(int i = 0; i < 3; i++)
        {
            ch = getc(srcx);
            if(ch == -1)
            {
                flag = 0;
                goto interruption;
            }
            Into_Binary(binary + i * 8, ch, 0);
        }
        interruption:
        for(int i = 0; i < 4; i++)
        {
            Into_Char(secret + i, binary + i * 6, 1);
        }
        fprintf(destx, "%s", secret);
    }
    
    fclose(srcx);
    fclose(destx);
}

void Out_Base64(const char dest[], const char src[])//解密函数//目标文件，源文件
{
    FILE* srcx = fopen(src, "r");
    if(srcx == NULL)
    {
        perror("source:");
        return;
    }
    FILE* destx = fopen(dest, "w");
    if(destx == NULL)
    {
        perror("destination:");
        return;
    }
    int flag = 1;
    while(flag)
    {
        char secret[4] = {0};//存储解密后数据//
        int binary[25] = {0};//6和8的最小公倍数为24
        char ch = 0;
        for(int i = 0; i < 4; i++)
        {
            ch = getc(srcx);
            if(ch == -1)
            {
                flag = 0;
                goto interruption;
            }
            Into_Binary(binary + i * 6, ch, 1);
        }
        interruption:
        for(int i = 0; i < 3; i++)
        {
            Into_Char(secret + i, binary + i * 8, 0);
        }
        fprintf(destx, "%s", secret);
    }
    
    fclose(srcx);
    fclose(destx);
}

int main()
{
    Into_Base64("test2.txt", "test1.txt");//把test1.txt加密后存到test2.txt
    Out_Base64("test3.txt", "test2.txt");//把test2.txt解密后存到test3.txt
    return 0;
}